/*
 * Copyright (c) 2012 Robert Burrell Donkin robertburrelldonkin.name
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software 
 * is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 */
package walrus.text;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;
import java.util.zip.ZipException;

import name.robertburrelldonkin.alfie.Actor;
import name.robertburrelldonkin.alfie.ActorFactory;


import walrus.base.ArticleBuffer;

public class GutenburgWordsActor implements Actor<File, WordCount> {

	public static final class Factory implements ActorFactory<File, WordCount> {

		public Actor<File, WordCount> build() {
			return pooling();
		}
		
	}
	
	public static GutenburgWordsActor pooling() {
		return new GutenburgWordsActor(System.out, new ArticleBuffer());
	}
	
	private final PrintStream out;
	private final ArticleBuffer buffer;
	
	public GutenburgWordsActor() {
		this(System.out, null);
	}
	
	private GutenburgWordsActor(final PrintStream out, final ArticleBuffer buffer) {
		this.out = out;
		this.buffer = buffer;		
	}
	
	public void printCount(final File file) throws IOException {
		count(file).printTo(out);
	}

	private WordCounter count(final File file) throws IOException {
		final List<String> words = words(file);
		WordCounter counter = new WordCounter();
		counter.setIgnoreCase(true).load(words);
		return counter;
	}

	private List<String> words(final File file) throws IOException {
		final GutenburgParser parser = new GutenburgParser(file);
		final SimpleWordParser wordParser = new SimpleWordParser();
		parser.setBuffer(buffer).read().feed(wordParser);
		final List<String> words = wordParser.getWords();
		return words;
	}

	public WordCount act(File subject) throws Exception {
		try {
			return count(subject).getCount();
		} catch (ZipException e) {
			System.out.println("[FAIL] Cannot unzip " + subject);
			throw e;
		} catch (InvalidFormatException e) {
			System.out.println("[FAIL] Invalid format " + subject);
			return EmptyWordCount.INSTANCE;
		} 
	}

	public void finish() {}
}
